package com.izocen.rules.core.engine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.LinkedBlockingDeque;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;

import org.apache.commons.lang.StringUtils;

import com.izocen.rules.common.EngineResponse;
import com.izocen.rules.common.ResponseMessage;
import com.izocen.rules.common.RuleEntity;
import com.izocen.rules.core.factory.RuleUnitFactory;
import com.izocen.rules.core.rule.RuleUnit;
import com.izocen.rules.interfaces.LessRuleEngine;

/**
 *@ClassName AbstractJpooRulesEngine
 * @Description: 
 * @Author pengyongjun
 * @Date 2020年6月19日
 */
public abstract class AbstractLessRulesEngine implements LessRuleEngine{

	//引擎拥有一个规则池，并能进行规则的增删改查
	protected LinkedBlockingDeque<RuleUnit> ll = new LinkedBlockingDeque<RuleUnit>();
	 
	private ScriptEngineManager manager = new ScriptEngineManager();
 	
	private ScriptEngine engine = manager.getEngineByName("js");
	 
	public abstract EngineResponse fire(Map<String, String> fact);

	public EngineResponse del(String ruleId) {
		if(StringUtils.isBlank(ruleId)) {
			return EngineResponse.fail_op("参数错误,ruleId:"+ruleId);
		}
		RuleUnit del = null;
        for(RuleUnit each : ll) {
        	String id = each.getId();
        	if(StringUtils.equals(id, ruleId)) {
        		del = each;
        		break;
        	}
        }
		if(del == null) {
			return EngineResponse.fail_op("规则池里面要删除的规则:["+ruleId+"]");
		}
        ll.remove(del);
		return EngineResponse.ok_op();
	}

	public EngineResponse add(RuleEntity ruleEntity) {
		ResponseMessage<RuleUnit> rm = RuleUnitFactory.create(ruleEntity);
		if(rm.getCode() == ResponseMessage.FAIL) {
			return EngineResponse.fail_op(rm.getMsg());
		}
		RuleUnit ru = rm.getData();
		ru.setScriptEngine(engine);
		ll.add(ru);
		return EngineResponse.ok_op();
	}

	public EngineResponse get(String ruleId) {
		if(StringUtils.isBlank(ruleId)) {
			return EngineResponse.fail_op("参数错误,ruleId:"+ruleId);
		}
		RuleUnit rule = null;
        for(RuleUnit each : ll) {
        	String id = each.getId();
        	if(StringUtils.equals(id, ruleId)) {
        		rule = each;
        		break;
        	}
        }
		if(rule == null) {
			return EngineResponse.fail_op("规则池里面不存在规则:["+ruleId+"]");
		}
		List<RuleUnit> list = new ArrayList<RuleUnit>();
		list.add(rule);
		return EngineResponse.ok_query(list);
	}

	public EngineResponse update(RuleEntity ruleEntity) {
		if(ruleEntity == null) {
			return EngineResponse.fail_op("参数错误,RuleEntity对象为null");
		}
		String ruleId = ruleEntity.getId();
		if(StringUtils.isBlank(ruleId)) {
			return EngineResponse.fail_op("参数错误,ruleId:"+ruleId);
		}
		this.del(ruleId);
		this.add(ruleEntity);
		return EngineResponse.ok_op();
	}

	public EngineResponse getRulePool() {
	   List<RuleUnit> list = new ArrayList<RuleUnit>();
	   if(ll == null || ll.isEmpty()) {
		   return EngineResponse.ok_query(list);
	   }
	   for(RuleUnit each : ll) {
		   list.add(each);
	   }	
	   return EngineResponse.ok_query(list);
	}
	
	protected EngineResponse assebleFireResult(Map<String,List<String>> result) {
		EngineResponse er = new EngineResponse();
		if(result == null || result.isEmpty()) {
			er.setMatchCode(EngineResponse.ENGINE_MATCH_RES_FAIL);
			return er;
		}
		er.setMatchCode(EngineResponse.ENGINE_MATCH_RES_SUCC);
		er.setFireResult(result);
		return er;
	}
	
}
